/******************************************************************************************
 * Import
 ******************************************************************************************/

// module
import _ from 'lodash';

/******************************************************************************************
 * Export Class
 ******************************************************************************************/

export default class Valid {

    /**
     * 验证值是否是符合要求的整数
     * 
     * @param {Any} value 需要验证的值
     * @param {Int} minValue 允许的最小值
     * @param {Int} maxValue 允许的最大值
     */
    static int(value, minValue, maxValue) {

        // 确认是整数
        if (!this.regex(value, /^\d+$/)) {
            return false;
        }

        // 对比值大小
        if (_.isInteger(minValue) && _.isInteger(maxValue)) {
            value = parseInt(value);
            return value <= maxValue && value >= minValue;
        }

        // 返回true
        return true;
    }

    /**
     * 验证值是否是符合要求的小数
     * 
     * @param {Any} value 需要验证的值
     * @param {Float} minValue 允许的最小值
     * @param {Float} maxValue 允许的最大值
     * @param {Int} minDigit 允许的的小数最小位数
     * @param {Int} maxDigit 允许的的小数最大位数
     */
    static float(value, minValue, maxValue, minDigit, maxDigit) {

        // 确认是数字
        if (!this.regex(value, /^(-?\d+)(\.\d+)?$/)) {
            return false;
        }

        // 对比值大小
        if (_.isNumber(minValue) && _.isNumber(maxValue)) {
            value = parseFloat(value);
            if (!(value <= maxValue && value >= minValue)) {
                return false;
            }
        }

        // 对比小数位数
        if (_.isInteger(minDigit) && _.isInteger(maxDigit)) {
            value = value.toString();
            const tmp = value.split('.');
            let digit = 0;
            if (tmp.length === 2) {
                digit = tmp[1].length;
            }
            return digit <= maxDigit && digit >= minDigit;
        }

        // 返回true
        return true;
    }

    /**
     * 验证值是否是符合要求的字符串
     * 
     * @param {Any} value 需要验证的值
     * @param {Int} minLength 允许的最小长度
     * @param {Int} maxLength 允许的最大长度
     */
    static string(value, minLength, maxLength) {

        // 确认是字符串
        if (!_.isString(value)) {
            return false;
        }

        // 对比长度
        if (_.isInteger(minLength) && _.isInteger(maxLength)) {
            const length = value.length;
            return length <= maxLength && length >= minLength;
        }

        // 返回true
        return true;
    }

    /**
     * 验证值是否是符合要求的数组
     * 
     * @param {Any} value 需要验证的值
     * @param {Int} minLength 允许的最小长度
     * @param {Int} maxLength 允许的最大长度
     */
    static array(value, minLength, maxLength) {

        // 确认是数组
        if (!_.isArray(value)) {
            return false;
        }

        // 对比长度
        if (_.isInteger(minLength) && _.isInteger(maxLength)) {
            const length = value.length;
            return length <= maxLength && length >= minLength;
        }

        // 返回true
        return true;
    }

    /**
     * 验证值是否是符合要求的对象
     * 
     * @param {Any} value 需要验证的值
     * @param {Array} contain 必须包含的key或key数组
     */
    static object(value, contain) {

        // lodash看的object验证对array和function也是友好的，所以如果是array或function也返回错误
        if (_.isArray(value) || _.isFunction(value)) {
            return false;
        }

        // 确认是对象
        if (!_.isObject(value)) {
            return false;
        }

        // 对比包含的keys
        if (_.isArray(contain) && contain.length > 0) {
            for (let item of contain) {
                if (!_.has(value, item)) {
                    return false;
                }
            }
        }

        // 返回true
        return true;
    }

    /**
     * 验证值是否为调用的函数
     * 
     * @param {Any} value 待验证的值
     */
    static function(value) {
        return _.isFunction(value);
    }

    /**
     * 验证值是否是符合某个正则表达式要求
     * 
     * @param {Any} value 需要验证的值
     * @param {RegExp} regex 需要进行对比的正则表达式
     */
    static regex(value, regex) {
        return regex.test(value);
    }
}
